#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <string>
#include <assert.h>
using namespace std;

#define THREAD_NUM 4
#define CALL_BACK_NUM 4
typedef void (*func_t)(string name,pthread_mutex_t *mtx,pthread_cond_t *cond);
volatile bool quit = false;
class ThreadData
{
public:
    ThreadData(string name,func_t callback_fun,pthread_mutex_t *mtx,pthread_cond_t *cond)//
    :_name(name)
    ,_callback_fun(callback_fun)
    ,_mtx(mtx)
    ,_cond(cond)
    {}

    //传入不同线程对应回调函数的参数
    string _name;
    func_t _callback_fun;
    pthread_mutex_t * _mtx;
    pthread_cond_t *_cond;
};
void func1(const string name,pthread_mutex_t *mtx,pthread_cond_t *cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mtx);
        pthread_cond_wait(cond,mtx);
        cout<<name<<" is running--播放视频"<<endl;
        pthread_mutex_unlock(mtx);
    }
}

void func2(const string name,pthread_mutex_t *mtx,pthread_cond_t *cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mtx);
        pthread_cond_wait(cond,mtx);
        cout<<name<<" is running--下载"<<endl;
        pthread_mutex_unlock(mtx);
    }
}

void func3(const string name,pthread_mutex_t *mtx,pthread_cond_t *cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mtx);
        pthread_cond_wait(cond,mtx);
        cout<<name<<" is running--扫描用户信息"<<endl;
        pthread_mutex_unlock(mtx);
    }
}

void func4(const string name,pthread_mutex_t *mtx,pthread_cond_t *cond)
{
    while(!quit)
    {
        pthread_mutex_lock(mtx);
        pthread_cond_wait(cond,mtx);
        cout<<name<<" is running--清理缓存"<<endl;
        pthread_mutex_unlock(mtx);
    }
}

void* Entrance(void *args)
{
    ThreadData* td = (ThreadData*)args;
    td->_callback_fun(td->_name,td->_mtx,td->_cond);
    delete td;
    return nullptr;
}

int main()
{
    pthread_mutex_t mtx;
    pthread_cond_t cond;
    pthread_mutex_init(&mtx,nullptr);
    pthread_cond_init(&cond,nullptr);
    pthread_t tid[THREAD_NUM];
    func_t callback[CALL_BACK_NUM] = {func1,func2,func3,func4};
    //创建一批线程
    for(int i = 0;i<THREAD_NUM;i++)
    {
        string s = "thread ";
        s += to_string(i+1);
        ThreadData* td = new ThreadData(s,callback[i],&mtx,&cond);
        int tem = pthread_create(tid+i,nullptr,Entrance,(void*)td);
        assert(tem == 0);
    }
    sleep(5);
    int cnt = 5;
    while(cnt)
    {
        cout<<"----------"<<cnt<<"----------"<<endl;
        pthread_cond_broadcast(&cond);
        sleep(1);
        cnt--;
    }
    quit = true;
    cout<<"为了退出再唤醒一次"<<endl;
    pthread_cond_broadcast(&cond);
    //回收线程
    for(int i = 0;i<THREAD_NUM;i++)
    {
        pthread_join(tid[i],nullptr);
        cout<<"线程回收成功"<<endl;
    }
    pthread_mutex_destroy(&mtx);
    pthread_cond_destroy(&cond);
    return 0;
}